<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha256-CTSx/A06dm1B063156EVh15m6Y67pAjZZaQc89LLSrU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.css" integrity="sha256-vQkngPS8jiHHH0I6ABTZroZk8NPZ7b+MUReOFE9UsXQ=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"rjyblog.gitee.io","root":"/","images":"/images","scheme":"Pisces","darkmode":false,"version":"8.18.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta property="og:type" content="website">
<meta property="og:title" content="任建勇的博客">
<meta property="og:url" content="https://rjyblog.gitee.io/index.html">
<meta property="og:site_name" content="任建勇的博客">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="Android, Java, Kotlin, Flutter, 前端技术, 设计模式">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://rjyblog.gitee.io/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>任建勇的博客</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">任建勇的博客</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jason"
      src="/images/avatar.png">
  <p class="site-author-name" itemprop="name">Jason</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">66</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">13</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">23</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/7f544006.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/7f544006.html" class="post-title-link" itemprop="url">Flutter Layout过程分析</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2024-01-14 10:24:54 / 修改时间：10:26:00" itemprop="dateCreated datePublished" datetime="2024-01-14T10:24:54+08:00">2024-01-14</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Flutter/" itemprop="url" rel="index"><span itemprop="name">Flutter</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>layout的基本流程：</p>
<ol>
<li>parent将约束信息传递给child，来限制child的最大宽高；</li>
<li>child根据根据约束信息确认自己的大小(如果儿子还有孙子，则儿子继续执行所有1~4的布局流程)；</li>
<li>parent根据child返回的大小来确定自己的大小；</li>
<li>parent确定child的位置偏移，并将位置偏移记录在child.parentData.offset中；</li>
</ol>
<h2 id="Center的布局"><a href="#Center的布局" class="headerlink" title="Center的布局"></a>Center的布局</h2><figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//RenderPositionedBox</span></span><br><span class="line">  <span class="keyword">void</span> performLayout() &#123;</span><br><span class="line">    <span class="keyword">final</span> BoxConstraints constraints = <span class="keyword">this</span>.constraints;</span><br><span class="line">    <span class="comment">//当需要缩放，或者约束的宽度为无限大时 shrinkWrapWidth=true</span></span><br><span class="line">    <span class="keyword">final</span> <span class="built_in">bool</span> shrinkWrapWidth = _widthFactor != <span class="keyword">null</span> || constraints.maxWidth == <span class="built_in">double</span>.infinity;</span><br><span class="line">    <span class="comment">//同上</span></span><br><span class="line">    <span class="keyword">final</span> <span class="built_in">bool</span> shrinkWrapHeight = _heightFactor != <span class="keyword">null</span> || constraints.maxHeight == <span class="built_in">double</span>.infinity;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (child != <span class="keyword">null</span>) &#123;</span><br><span class="line">      <span class="comment">//child根据parent的约束进行布局，layout最终还是会调用performLayout来计算布局</span></span><br><span class="line">      child!.layout(constraints.loosen(), parentUsesSize: <span class="keyword">true</span>);</span><br><span class="line">      <span class="comment">//</span></span><br><span class="line">      size = constraints.constrain(Size(</span><br><span class="line">        shrinkWrapWidth ? child!.size.width * (_widthFactor ?? <span class="number">1.0</span>) : <span class="built_in">double</span>.infinity,</span><br><span class="line">        shrinkWrapHeight ? child!.size.height * (_heightFactor ?? <span class="number">1.0</span>) : <span class="built_in">double</span>.infinity,</span><br><span class="line">      ));</span><br><span class="line">      alignChild();</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">//如果没有child，则返回一个无限大的布局大小</span></span><br><span class="line">      size = constraints.constrain(Size(</span><br><span class="line">        shrinkWrapWidth ? <span class="number">0.0</span> : <span class="built_in">double</span>.infinity,</span><br><span class="line">        shrinkWrapHeight ? <span class="number">0.0</span> : <span class="built_in">double</span>.infinity,</span><br><span class="line">      ));</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/7f544006.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/60dc81b5.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/60dc81b5.html" class="post-title-link" itemprop="url">Flutter渲染流程</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2024-01-14 10:23:11" itemprop="dateCreated datePublished" datetime="2024-01-14T10:23:11+08:00">2024-01-14</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2024-01-15 11:49:42" itemprop="dateModified" datetime="2024-01-15T11:49:42+08:00">2024-01-15</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Flutter/" itemprop="url" rel="index"><span itemprop="name">Flutter</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h2 id="Flutter启动"><a href="#Flutter启动" class="headerlink" title="Flutter启动"></a>Flutter启动</h2><p>main函数就是Flutter app的启动入口，在main函数中调用runApp就可以启动我们的界面了：</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> main() &#123;</span><br><span class="line">  runApp(<span class="keyword">const</span> MyApp());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>下面是runApp的源码：</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> runApp(Widget app) &#123;</span><br><span class="line">  <span class="comment">//binding的初始化</span></span><br><span class="line">  <span class="keyword">final</span> WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized();</span><br><span class="line">  <span class="comment">//启动绘制流程</span></span><br><span class="line">  binding</span><br><span class="line">    ..scheduleAttachRootWidget(binding.wrapWithDefaultView(app))</span><br><span class="line">    ..scheduleWarmUpFrame();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">WidgetsFlutterBinding</span> <span class="keyword">extends</span> <span class="title">BindingBase</span> </span></span><br><span class="line"><span class="class">    <span class="title">with</span> <span class="title">GestureBinding</span>, </span></span><br><span class="line"><span class="class">        <span class="title">SchedulerBinding</span>, </span></span><br><span class="line"><span class="class">        <span class="title">ServicesBinding</span>, </span></span><br><span class="line"><span class="class">        <span class="title">PaintingBinding</span>, </span></span><br><span class="line"><span class="class">        <span class="title">SemanticsBinding</span>, </span></span><br><span class="line"><span class="class">        <span class="title">RendererBinding</span>, </span></span><br><span class="line"><span class="class">        <span class="title">WidgetsBinding</span> </span>&#123;</span><br><span class="line">  <span class="keyword">static</span> WidgetsBinding ensureInitialized() &#123;</span><br><span class="line">    <span class="keyword">if</span> (WidgetsBinding._instance == <span class="keyword">null</span>) &#123;</span><br><span class="line">      WidgetsFlutterBinding();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> WidgetsBinding.instance;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>WidgetsFlutterBinding继承自BindingBase，但通过with语句混入了各种Binding，我们都知道mixin的类是没有构造函数的。ensureInitialized()会调用WidgetsFlutterBinding构造函数，主要实现在BindingBase构造函数中。BindingBase在构造函数中会调用initInstances()，这个函数在各个mixin的Binding类中都有实现，首先调用的是WidgetsBinding的实现，然后一层一层调用super.initInstances()，这样所以Binding类的initInstances()都会被执行。下面是initInstances的调用时序：</p>
<pre class="mermaid">

zenuml
WidgetsBinding.initInstances {
    RendererBinding.initInstances {
        SemanticsBinding.initInstances {
            PaintingBinding.initInstances {
                ServicesBinding.initInstances {
                    SchedulerBinding.initInstances {
                        GestureBinding.initInstances {
                            return
                        }
                        return
                    }
                    return
                }
                createImageCache()
                return
            }
            return
        }
        createRootPipelineOwner
        return
    }
    &quot;_buildOwner &#x3D; BuildOwner();&quot;
    &quot;buildOwner!.onBuildScheduled &#x3D; _handleBuildScheduled;&quot;
}
</pre>

<ul>
<li><p>GestureBinding.initInstances：会向PlatformDispatcher设置手势事件的回调，会把从flutter engine接收的数据包解析成PointerEvent，包括PointerDownEvent、PointerUpEvent等；</p>
</li>
<li><p>SchedulerBinding提供了scheduleFrame()接口来主动触发一次绘制刷新。并且还会向PlatformDispatcher注册屏幕刷新事件的回调，如下：</p>
  <figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> ensureFrameCallbacksRegistered() &#123;</span><br><span class="line">platformDispatcher.onBeginFrame ??= _handleBeginFrame;</span><br><span class="line">platformDispatcher.onDrawFrame ??= _handleDrawFrame;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

</li>
</ul>
<h3 id="启动渲染流程"><a href="#启动渲染流程" class="headerlink" title="启动渲染流程"></a>启动渲染流程</h3><p>在<code>packages/flutter/lib/src/widgets/binding.dart</code>中的<code>WidgetsBinding.drawFrame()</code>的注释中介绍了渲染流程。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/60dc81b5.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/507c84ae.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/507c84ae.html" class="post-title-link" itemprop="url">Flutter三棵树</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2024-01-14 10:21:04" itemprop="dateCreated datePublished" datetime="2024-01-14T10:21:04+08:00">2024-01-14</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2024-01-15 09:42:57" itemprop="dateModified" datetime="2024-01-15T09:42:57+08:00">2024-01-15</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Flutter/" itemprop="url" rel="index"><span itemprop="name">Flutter</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>下面是Flutter官网提供的关于三棵树的介绍，比较形象，这里直接摘录了，可以参考<a target="_blank" rel="noopener external nofollow noreferrer" href="https://flutter.cn/docs/resources/architectural-overview#build-from-widget-to-element">原文</a>。</p>
<figure class="highlight dart"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">Container(</span><br><span class="line">  color: Colors.blue,</span><br><span class="line">  child: Row(</span><br><span class="line">    children: [</span><br><span class="line">      Image.network(<span class="string">&#x27;https://www.example.com/1.png&#x27;</span>),</span><br><span class="line">      <span class="keyword">const</span> Text(<span class="string">&#x27;A&#x27;</span>),</span><br><span class="line">    ],</span><br><span class="line">  ),</span><br><span class="line">);</span><br></pre></td></tr></table></figure>

<p>上面这段代码构建的三棵树如下所示：</p>
<p><img src="/images/Flutter/Flutter%E4%B8%89%E6%A3%B5%E6%A0%91%E7%A4%BA%E6%84%8F%E5%9B%BE.webp" alt="Flutter三棵树示意图"></p>
<p>在开发调试阶段使用<a target="_blank" rel="noopener external nofollow noreferrer" href="https://flutter.cn/docs/development/tools/devtools/inspector">Flutter inspector</a>可以看出实际的Widget树要比代码中描述的层级更深。</p>
<h2 id="Widget树"><a href="#Widget树" class="headerlink" title="Widget树"></a>Widget树</h2><p>先看下Widget的家族：</p>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentstyletype="text/css" height="494px" preserveAspectRatio="none" style="width:967px;height:494px;background:#FFFFFF;" version="1.1" viewBox="0 0 967 494" width="967px" zoomAndPan="magnify"><defs/><g><!--class Widget--><g id="elem_Widget"><rect codeline="1" fill="#F1F1F1" height="48" id="Widget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="82" x="588" y="7"/><ellipse cx="603" cy="23" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M605.0781,24.8125 L605.4688,25.7969 L605.0781,25.7969 C604.625,25.7969 604.5156,25.8125 604.3594,25.9219 C604.1094,26.0781 603.9531,26.3594 603.9531,26.6563 C603.9531,26.9219 604.0938,27.1719 604.3125,27.3281 C604.4531,27.4531 604.6563,27.5 605.0781,27.5 L607.4375,27.5 C607.7969,27.5 608.0156,27.4688 608.1563,27.375 C608.4063,27.2344 608.5625,26.9375 608.5625,26.6563 C608.5625,26.375 608.4219,26.125 608.2031,25.9688 C608.0313,25.8281 607.875,25.7969 607.4063,25.7969 L604.0156,17.5938 L600.3438,17.5938 C599.8906,17.5938 599.7656,17.6094 599.6094,17.7031 C599.3594,17.875 599.2031,18.1563 599.2031,18.4375 C599.2031,18.7188 599.3438,18.9688 599.5625,19.1406 C599.7344,19.25 599.9063,19.2813 600.3438,19.2813 L601.4219,19.2813 L598.7813,25.7969 C598.3594,25.7969 598.2031,25.8125 598.0469,25.9219 C597.7969,26.0781 597.6406,26.3594 597.6406,26.6563 C597.6406,27.2188 598.0156,27.5 598.7656,27.5 L601.0313,27.5 C601.3906,27.5 601.6094,27.4688 601.7344,27.375 C602,27.2344 602.1406,26.9375 602.1406,26.6563 C602.1406,26.375 602.0156,26.125 601.7969,25.9531 C601.625,25.8281 601.4844,25.7969 601.0313,25.7969 L600.6406,25.7969 L601.0313,24.8125 L605.0781,24.8125 Z M604.375,23.1094 L601.7031,23.1094 L603.0469,19.8438 L604.375,23.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="50" x="617" y="27.8467">Widget</text><line style="stroke:#181818;stroke-width:0.5;" x1="589" x2="669" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="589" x2="669" y1="47" y2="47"/></g><!--class RenderObjectWidget--><g id="elem_RenderObjectWidget"><rect codeline="3" fill="#F1F1F1" height="48" id="RenderObjectWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="180" x="257" y="115"/><ellipse cx="272" cy="131" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M274.0781,132.8125 L274.4688,133.7969 L274.0781,133.7969 C273.625,133.7969 273.5156,133.8125 273.3594,133.9219 C273.1094,134.0781 272.9531,134.3594 272.9531,134.6563 C272.9531,134.9219 273.0938,135.1719 273.3125,135.3281 C273.4531,135.4531 273.6563,135.5 274.0781,135.5 L276.4375,135.5 C276.7969,135.5 277.0156,135.4688 277.1563,135.375 C277.4063,135.2344 277.5625,134.9375 277.5625,134.6563 C277.5625,134.375 277.4219,134.125 277.2031,133.9688 C277.0313,133.8281 276.875,133.7969 276.4063,133.7969 L273.0156,125.5938 L269.3438,125.5938 C268.8906,125.5938 268.7656,125.6094 268.6094,125.7031 C268.3594,125.875 268.2031,126.1563 268.2031,126.4375 C268.2031,126.7188 268.3438,126.9688 268.5625,127.1406 C268.7344,127.25 268.9063,127.2813 269.3438,127.2813 L270.4219,127.2813 L267.7813,133.7969 C267.3594,133.7969 267.2031,133.8125 267.0469,133.9219 C266.7969,134.0781 266.6406,134.3594 266.6406,134.6563 C266.6406,135.2188 267.0156,135.5 267.7656,135.5 L270.0313,135.5 C270.3906,135.5 270.6094,135.4688 270.7344,135.375 C271,135.2344 271.1406,134.9375 271.1406,134.6563 C271.1406,134.375 271.0156,134.125 270.7969,133.9531 C270.625,133.8281 270.4844,133.7969 270.0313,133.7969 L269.6406,133.7969 L270.0313,132.8125 L274.0781,132.8125 Z M273.375,131.1094 L270.7031,131.1094 L272.0469,127.8438 L273.375,131.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="148" x="286" y="135.8467">RenderObjectWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="258" x2="436" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="258" x2="436" y1="155" y2="155"/></g><!--class SingleChildRenderObjectWidget--><g id="elem_SingleChildRenderObjectWidget"><rect codeline="5" fill="#F1F1F1" height="48" id="SingleChildRenderObjectWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="260" x="7" y="223"/><ellipse cx="22" cy="239" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M24.0781,240.8125 L24.4688,241.7969 L24.0781,241.7969 C23.625,241.7969 23.5156,241.8125 23.3594,241.9219 C23.1094,242.0781 22.9531,242.3594 22.9531,242.6563 C22.9531,242.9219 23.0938,243.1719 23.3125,243.3281 C23.4531,243.4531 23.6563,243.5 24.0781,243.5 L26.4375,243.5 C26.7969,243.5 27.0156,243.4688 27.1563,243.375 C27.4063,243.2344 27.5625,242.9375 27.5625,242.6563 C27.5625,242.375 27.4219,242.125 27.2031,241.9688 C27.0313,241.8281 26.875,241.7969 26.4063,241.7969 L23.0156,233.5938 L19.3438,233.5938 C18.8906,233.5938 18.7656,233.6094 18.6094,233.7031 C18.3594,233.875 18.2031,234.1563 18.2031,234.4375 C18.2031,234.7188 18.3438,234.9688 18.5625,235.1406 C18.7344,235.25 18.9063,235.2813 19.3438,235.2813 L20.4219,235.2813 L17.7813,241.7969 C17.3594,241.7969 17.2031,241.8125 17.0469,241.9219 C16.7969,242.0781 16.6406,242.3594 16.6406,242.6563 C16.6406,243.2188 17.0156,243.5 17.7656,243.5 L20.0313,243.5 C20.3906,243.5 20.6094,243.4688 20.7344,243.375 C21,243.2344 21.1406,242.9375 21.1406,242.6563 C21.1406,242.375 21.0156,242.125 20.7969,241.9531 C20.625,241.8281 20.4844,241.7969 20.0313,241.7969 L19.6406,241.7969 L20.0313,240.8125 L24.0781,240.8125 Z M23.375,239.1094 L20.7031,239.1094 L22.0469,235.8438 L23.375,239.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="228" x="36" y="243.8467">SingleChildRenderObjectWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="266" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="266" y1="263" y2="263"/></g><!--class MultiChildRenderObjectWidget--><g id="elem_MultiChildRenderObjectWidget"><rect codeline="6" fill="#F1F1F1" height="48" id="MultiChildRenderObjectWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="250" x="302" y="223"/><ellipse cx="317" cy="239" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M319.0781,240.8125 L319.4688,241.7969 L319.0781,241.7969 C318.625,241.7969 318.5156,241.8125 318.3594,241.9219 C318.1094,242.0781 317.9531,242.3594 317.9531,242.6563 C317.9531,242.9219 318.0938,243.1719 318.3125,243.3281 C318.4531,243.4531 318.6563,243.5 319.0781,243.5 L321.4375,243.5 C321.7969,243.5 322.0156,243.4688 322.1563,243.375 C322.4063,243.2344 322.5625,242.9375 322.5625,242.6563 C322.5625,242.375 322.4219,242.125 322.2031,241.9688 C322.0313,241.8281 321.875,241.7969 321.4063,241.7969 L318.0156,233.5938 L314.3438,233.5938 C313.8906,233.5938 313.7656,233.6094 313.6094,233.7031 C313.3594,233.875 313.2031,234.1563 313.2031,234.4375 C313.2031,234.7188 313.3438,234.9688 313.5625,235.1406 C313.7344,235.25 313.9063,235.2813 314.3438,235.2813 L315.4219,235.2813 L312.7813,241.7969 C312.3594,241.7969 312.2031,241.8125 312.0469,241.9219 C311.7969,242.0781 311.6406,242.3594 311.6406,242.6563 C311.6406,243.2188 312.0156,243.5 312.7656,243.5 L315.0313,243.5 C315.3906,243.5 315.6094,243.4688 315.7344,243.375 C316,243.2344 316.1406,242.9375 316.1406,242.6563 C316.1406,242.375 316.0156,242.125 315.7969,241.9531 C315.625,241.8281 315.4844,241.7969 315.0313,241.7969 L314.6406,241.7969 L315.0313,240.8125 L319.0781,240.8125 Z M318.375,239.1094 L315.7031,239.1094 L317.0469,235.8438 L318.375,239.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="218" x="331" y="243.8467">MultiChildRenderObjectWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="303" x2="551" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="303" x2="551" y1="263" y2="263"/></g><!--class Flex--><g id="elem_Flex"><rect fill="#F1F1F1" height="48" id="Flex" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="61" x="396.5" y="331"/><ellipse cx="411.5" cy="347" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M413.8438,342.6719 C412.9063,342.2344 412.3125,342.0938 411.4375,342.0938 C408.8125,342.0938 406.8125,344.1719 406.8125,346.8906 L406.8125,348.0156 C406.8125,350.5938 408.9219,352.4844 411.8125,352.4844 C413.0313,352.4844 414.1875,352.1875 414.9375,351.6406 C415.5156,351.2344 415.8438,350.7813 415.8438,350.3906 C415.8438,349.9375 415.4531,349.5469 414.9844,349.5469 C414.7656,349.5469 414.5625,349.625 414.375,349.8125 C413.9219,350.2969 413.9219,350.2969 413.7344,350.3906 C413.3125,350.6563 412.625,350.7813 411.8594,350.7813 C409.8125,350.7813 408.5156,349.6875 408.5156,347.9844 L408.5156,346.8906 C408.5156,345.1094 409.7656,343.7969 411.5,343.7969 C412.0781,343.7969 412.6875,343.9531 413.1563,344.2031 C413.6406,344.4844 413.8125,344.7031 413.9063,345.1094 C413.9688,345.5156 414,345.6406 414.1406,345.7656 C414.2813,345.9063 414.5156,346.0156 414.7344,346.0156 C415,346.0156 415.2656,345.875 415.4375,345.6563 C415.5469,345.5 415.5781,345.3125 415.5781,344.8906 L415.5781,343.4688 C415.5781,343.0313 415.5625,342.9063 415.4688,342.75 C415.3125,342.4844 415.0313,342.3438 414.7344,342.3438 C414.4375,342.3438 414.2344,342.4375 414.0156,342.75 L413.8438,342.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="29" x="425.5" y="351.8467">Flex</text><line style="stroke:#181818;stroke-width:0.5;" x1="397.5" x2="456.5" y1="363" y2="363"/><line style="stroke:#181818;stroke-width:0.5;" x1="397.5" x2="456.5" y1="371" y2="371"/></g><!--class Column--><g id="elem_Column"><rect fill="#F1F1F1" height="48" id="Column" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="86" x="330" y="439"/><ellipse cx="345" cy="455" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M347.3438,450.6719 C346.4063,450.2344 345.8125,450.0938 344.9375,450.0938 C342.3125,450.0938 340.3125,452.1719 340.3125,454.8906 L340.3125,456.0156 C340.3125,458.5938 342.4219,460.4844 345.3125,460.4844 C346.5313,460.4844 347.6875,460.1875 348.4375,459.6406 C349.0156,459.2344 349.3438,458.7813 349.3438,458.3906 C349.3438,457.9375 348.9531,457.5469 348.4844,457.5469 C348.2656,457.5469 348.0625,457.625 347.875,457.8125 C347.4219,458.2969 347.4219,458.2969 347.2344,458.3906 C346.8125,458.6563 346.125,458.7813 345.3594,458.7813 C343.3125,458.7813 342.0156,457.6875 342.0156,455.9844 L342.0156,454.8906 C342.0156,453.1094 343.2656,451.7969 345,451.7969 C345.5781,451.7969 346.1875,451.9531 346.6563,452.2031 C347.1406,452.4844 347.3125,452.7031 347.4063,453.1094 C347.4688,453.5156 347.5,453.6406 347.6406,453.7656 C347.7813,453.9063 348.0156,454.0156 348.2344,454.0156 C348.5,454.0156 348.7656,453.875 348.9375,453.6563 C349.0469,453.5 349.0781,453.3125 349.0781,452.8906 L349.0781,451.4688 C349.0781,451.0313 349.0625,450.9063 348.9688,450.75 C348.8125,450.4844 348.5313,450.3438 348.2344,450.3438 C347.9375,450.3438 347.7344,450.4375 347.5156,450.75 L347.3438,450.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="54" x="359" y="459.8467">Column</text><line style="stroke:#181818;stroke-width:0.5;" x1="331" x2="415" y1="471" y2="471"/><line style="stroke:#181818;stroke-width:0.5;" x1="331" x2="415" y1="479" y2="479"/></g><!--class Row--><g id="elem_Row"><rect fill="#F1F1F1" height="48" id="Row" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="62" x="451" y="439"/><ellipse cx="466" cy="455" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M468.3438,450.6719 C467.4063,450.2344 466.8125,450.0938 465.9375,450.0938 C463.3125,450.0938 461.3125,452.1719 461.3125,454.8906 L461.3125,456.0156 C461.3125,458.5938 463.4219,460.4844 466.3125,460.4844 C467.5313,460.4844 468.6875,460.1875 469.4375,459.6406 C470.0156,459.2344 470.3438,458.7813 470.3438,458.3906 C470.3438,457.9375 469.9531,457.5469 469.4844,457.5469 C469.2656,457.5469 469.0625,457.625 468.875,457.8125 C468.4219,458.2969 468.4219,458.2969 468.2344,458.3906 C467.8125,458.6563 467.125,458.7813 466.3594,458.7813 C464.3125,458.7813 463.0156,457.6875 463.0156,455.9844 L463.0156,454.8906 C463.0156,453.1094 464.2656,451.7969 466,451.7969 C466.5781,451.7969 467.1875,451.9531 467.6563,452.2031 C468.1406,452.4844 468.3125,452.7031 468.4063,453.1094 C468.4688,453.5156 468.5,453.6406 468.6406,453.7656 C468.7813,453.9063 469.0156,454.0156 469.2344,454.0156 C469.5,454.0156 469.7656,453.875 469.9375,453.6563 C470.0469,453.5 470.0781,453.3125 470.0781,452.8906 L470.0781,451.4688 C470.0781,451.0313 470.0625,450.9063 469.9688,450.75 C469.8125,450.4844 469.5313,450.3438 469.2344,450.3438 C468.9375,450.3438 468.7344,450.4375 468.5156,450.75 L468.3438,450.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="30" x="480" y="459.8467">Row</text><line style="stroke:#181818;stroke-width:0.5;" x1="452" x2="512" y1="471" y2="471"/><line style="stroke:#181818;stroke-width:0.5;" x1="452" x2="512" y1="479" y2="479"/></g><!--class StatefulWidget--><g id="elem_StatefulWidget"><rect codeline="13" fill="#F1F1F1" height="48" id="StatefulWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="137" x="472.5" y="115"/><ellipse cx="487.5" cy="131" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M489.5781,132.8125 L489.9688,133.7969 L489.5781,133.7969 C489.125,133.7969 489.0156,133.8125 488.8594,133.9219 C488.6094,134.0781 488.4531,134.3594 488.4531,134.6563 C488.4531,134.9219 488.5938,135.1719 488.8125,135.3281 C488.9531,135.4531 489.1563,135.5 489.5781,135.5 L491.9375,135.5 C492.2969,135.5 492.5156,135.4688 492.6563,135.375 C492.9063,135.2344 493.0625,134.9375 493.0625,134.6563 C493.0625,134.375 492.9219,134.125 492.7031,133.9688 C492.5313,133.8281 492.375,133.7969 491.9063,133.7969 L488.5156,125.5938 L484.8438,125.5938 C484.3906,125.5938 484.2656,125.6094 484.1094,125.7031 C483.8594,125.875 483.7031,126.1563 483.7031,126.4375 C483.7031,126.7188 483.8438,126.9688 484.0625,127.1406 C484.2344,127.25 484.4063,127.2813 484.8438,127.2813 L485.9219,127.2813 L483.2813,133.7969 C482.8594,133.7969 482.7031,133.8125 482.5469,133.9219 C482.2969,134.0781 482.1406,134.3594 482.1406,134.6563 C482.1406,135.2188 482.5156,135.5 483.2656,135.5 L485.5313,135.5 C485.8906,135.5 486.1094,135.4688 486.2344,135.375 C486.5,135.2344 486.6406,134.9375 486.6406,134.6563 C486.6406,134.375 486.5156,134.125 486.2969,133.9531 C486.125,133.8281 485.9844,133.7969 485.5313,133.7969 L485.1406,133.7969 L485.5313,132.8125 L489.5781,132.8125 Z M488.875,131.1094 L486.2031,131.1094 L487.5469,127.8438 L488.875,131.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="105" x="501.5" y="135.8467">StatefulWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="473.5" x2="608.5" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="473.5" x2="608.5" y1="155" y2="155"/></g><!--class StatelessWidget--><g id="elem_StatelessWidget"><rect codeline="14" fill="#F1F1F1" height="48" id="StatelessWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="146" x="645" y="115"/><ellipse cx="660" cy="131" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M662.0781,132.8125 L662.4688,133.7969 L662.0781,133.7969 C661.625,133.7969 661.5156,133.8125 661.3594,133.9219 C661.1094,134.0781 660.9531,134.3594 660.9531,134.6563 C660.9531,134.9219 661.0938,135.1719 661.3125,135.3281 C661.4531,135.4531 661.6563,135.5 662.0781,135.5 L664.4375,135.5 C664.7969,135.5 665.0156,135.4688 665.1563,135.375 C665.4063,135.2344 665.5625,134.9375 665.5625,134.6563 C665.5625,134.375 665.4219,134.125 665.2031,133.9688 C665.0313,133.8281 664.875,133.7969 664.4063,133.7969 L661.0156,125.5938 L657.3438,125.5938 C656.8906,125.5938 656.7656,125.6094 656.6094,125.7031 C656.3594,125.875 656.2031,126.1563 656.2031,126.4375 C656.2031,126.7188 656.3438,126.9688 656.5625,127.1406 C656.7344,127.25 656.9063,127.2813 657.3438,127.2813 L658.4219,127.2813 L655.7813,133.7969 C655.3594,133.7969 655.2031,133.8125 655.0469,133.9219 C654.7969,134.0781 654.6406,134.3594 654.6406,134.6563 C654.6406,135.2188 655.0156,135.5 655.7656,135.5 L658.0313,135.5 C658.3906,135.5 658.6094,135.4688 658.7344,135.375 C659,135.2344 659.1406,134.9375 659.1406,134.6563 C659.1406,134.375 659.0156,134.125 658.7969,133.9531 C658.625,133.8281 658.4844,133.7969 658.0313,133.7969 L657.6406,133.7969 L658.0313,132.8125 L662.0781,132.8125 Z M661.375,131.1094 L658.7031,131.1094 L660.0469,127.8438 L661.375,131.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="114" x="674" y="135.8467">StatelessWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="646" x2="790" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="646" x2="790" y1="155" y2="155"/></g><!--class InheritedWidget--><g id="elem_InheritedWidget"><rect codeline="15" fill="#F1F1F1" height="48" id="InheritedWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="146" x="814" y="223"/><ellipse cx="829" cy="239" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M831.0781,240.8125 L831.4688,241.7969 L831.0781,241.7969 C830.625,241.7969 830.5156,241.8125 830.3594,241.9219 C830.1094,242.0781 829.9531,242.3594 829.9531,242.6563 C829.9531,242.9219 830.0938,243.1719 830.3125,243.3281 C830.4531,243.4531 830.6563,243.5 831.0781,243.5 L833.4375,243.5 C833.7969,243.5 834.0156,243.4688 834.1563,243.375 C834.4063,243.2344 834.5625,242.9375 834.5625,242.6563 C834.5625,242.375 834.4219,242.125 834.2031,241.9688 C834.0313,241.8281 833.875,241.7969 833.4063,241.7969 L830.0156,233.5938 L826.3438,233.5938 C825.8906,233.5938 825.7656,233.6094 825.6094,233.7031 C825.3594,233.875 825.2031,234.1563 825.2031,234.4375 C825.2031,234.7188 825.3438,234.9688 825.5625,235.1406 C825.7344,235.25 825.9063,235.2813 826.3438,235.2813 L827.4219,235.2813 L824.7813,241.7969 C824.3594,241.7969 824.2031,241.8125 824.0469,241.9219 C823.7969,242.0781 823.6406,242.3594 823.6406,242.6563 C823.6406,243.2188 824.0156,243.5 824.7656,243.5 L827.0313,243.5 C827.3906,243.5 827.6094,243.4688 827.7344,243.375 C828,243.2344 828.1406,242.9375 828.1406,242.6563 C828.1406,242.375 828.0156,242.125 827.7969,241.9531 C827.625,241.8281 827.4844,241.7969 827.0313,241.7969 L826.6406,241.7969 L827.0313,240.8125 L831.0781,240.8125 Z M830.375,239.1094 L827.7031,239.1094 L829.0469,235.8438 L830.375,239.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="114" x="843" y="243.8467">InheritedWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="815" x2="959" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="815" x2="959" y1="263" y2="263"/></g><!--class ProxyWidget--><g id="elem_ProxyWidget"><rect codeline="16" fill="#F1F1F1" height="48" id="ProxyWidget" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="121" x="826.5" y="115"/><ellipse cx="841.5" cy="131" fill="#A9DCDF" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M843.5781,132.8125 L843.9688,133.7969 L843.5781,133.7969 C843.125,133.7969 843.0156,133.8125 842.8594,133.9219 C842.6094,134.0781 842.4531,134.3594 842.4531,134.6563 C842.4531,134.9219 842.5938,135.1719 842.8125,135.3281 C842.9531,135.4531 843.1563,135.5 843.5781,135.5 L845.9375,135.5 C846.2969,135.5 846.5156,135.4688 846.6563,135.375 C846.9063,135.2344 847.0625,134.9375 847.0625,134.6563 C847.0625,134.375 846.9219,134.125 846.7031,133.9688 C846.5313,133.8281 846.375,133.7969 845.9063,133.7969 L842.5156,125.5938 L838.8438,125.5938 C838.3906,125.5938 838.2656,125.6094 838.1094,125.7031 C837.8594,125.875 837.7031,126.1563 837.7031,126.4375 C837.7031,126.7188 837.8438,126.9688 838.0625,127.1406 C838.2344,127.25 838.4063,127.2813 838.8438,127.2813 L839.9219,127.2813 L837.2813,133.7969 C836.8594,133.7969 836.7031,133.8125 836.5469,133.9219 C836.2969,134.0781 836.1406,134.3594 836.1406,134.6563 C836.1406,135.2188 836.5156,135.5 837.2656,135.5 L839.5313,135.5 C839.8906,135.5 840.1094,135.4688 840.2344,135.375 C840.5,135.2344 840.6406,134.9375 840.6406,134.6563 C840.6406,134.375 840.5156,134.125 840.2969,133.9531 C840.125,133.8281 839.9844,133.7969 839.5313,133.7969 L839.1406,133.7969 L839.5313,132.8125 L843.5781,132.8125 Z M842.875,131.1094 L840.2031,131.1094 L841.5469,127.8438 L842.875,131.1094 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="89" x="855.5" y="135.8467">ProxyWidget</text><line style="stroke:#181818;stroke-width:0.5;" x1="827.5" x2="946.5" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="827.5" x2="946.5" y1="155" y2="155"/></g><!--class Container--><g id="elem_Container"><rect fill="#F1F1F1" height="48" id="Container" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="103" x="666.5" y="223"/><ellipse cx="681.5" cy="239" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M683.8438,234.6719 C682.9063,234.2344 682.3125,234.0938 681.4375,234.0938 C678.8125,234.0938 676.8125,236.1719 676.8125,238.8906 L676.8125,240.0156 C676.8125,242.5938 678.9219,244.4844 681.8125,244.4844 C683.0313,244.4844 684.1875,244.1875 684.9375,243.6406 C685.5156,243.2344 685.8438,242.7813 685.8438,242.3906 C685.8438,241.9375 685.4531,241.5469 684.9844,241.5469 C684.7656,241.5469 684.5625,241.625 684.375,241.8125 C683.9219,242.2969 683.9219,242.2969 683.7344,242.3906 C683.3125,242.6563 682.625,242.7813 681.8594,242.7813 C679.8125,242.7813 678.5156,241.6875 678.5156,239.9844 L678.5156,238.8906 C678.5156,237.1094 679.7656,235.7969 681.5,235.7969 C682.0781,235.7969 682.6875,235.9531 683.1563,236.2031 C683.6406,236.4844 683.8125,236.7031 683.9063,237.1094 C683.9688,237.5156 684,237.6406 684.1406,237.7656 C684.2813,237.9063 684.5156,238.0156 684.7344,238.0156 C685,238.0156 685.2656,237.875 685.4375,237.6563 C685.5469,237.5 685.5781,237.3125 685.5781,236.8906 L685.5781,235.4688 C685.5781,235.0313 685.5625,234.9063 685.4688,234.75 C685.3125,234.4844 685.0313,234.3438 684.7344,234.3438 C684.4375,234.3438 684.2344,234.4375 684.0156,234.75 L683.8438,234.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="71" x="695.5" y="243.8467">Container</text><line style="stroke:#181818;stroke-width:0.5;" x1="667.5" x2="768.5" y1="255" y2="255"/><line style="stroke:#181818;stroke-width:0.5;" x1="667.5" x2="768.5" y1="263" y2="263"/></g><!--reverse link Widget to RenderObjectWidget--><g id="link_Widget_RenderObjectWidget"><path codeline="4" d="M571.146,53.7464 C523.944,71.4894 462.787,94.477 408.351,114.939 " fill="none" id="Widget-backto-RenderObjectWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="587.995,47.413,569.0349,48.1301,573.2572,59.3628,587.995,47.413" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link RenderObjectWidget to SingleChildRenderObjectWidget--><g id="link_RenderObjectWidget_SingleChildRenderObjectWidget"><path codeline="7" d="M285.3641,171.1111 C250.2611,188.8301 218.012,205.108 182.84,222.862 " fill="none" id="RenderObjectWidget-backto-SingleChildRenderObjectWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="301.433,163,282.6604,165.7548,288.0678,176.4674,301.433,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link RenderObjectWidget to MultiChildRenderObjectWidget--><g id="link_RenderObjectWidget_MultiChildRenderObjectWidget"><path codeline="8" d="M375.2024,177.3673 C388.5294,195.0253 396.012,204.941 409.399,222.678 " fill="none" id="RenderObjectWidget-backto-MultiChildRenderObjectWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="364.359,163,370.4133,180.9818,379.9915,173.7528,364.359,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link MultiChildRenderObjectWidget to Flex--><g id="link_MultiChildRenderObjectWidget_Flex"><path codeline="9" d="M427,289 C427,306.658 427,312.941 427,330.678 " fill="none" id="MultiChildRenderObjectWidget-backto-Flex" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="427,271,421,289,433,289,427,271" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Flex to Column--><g id="link_Flex_Column"><path codeline="10" d="M407.1122,395.0386 C398.1162,412.697 393.917,420.9408 384.881,438.6784 " fill="none" id="Flex-backto-Column" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="415.283,379,401.766,392.315,412.4584,397.7622,415.283,379" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Flex to Row--><g id="link_Flex_Row"><path codeline="11" d="M447.2238,394.9774 C456.3858,412.6358 460.696,420.9408 469.899,438.6784 " fill="none" id="Flex-backto-Row" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="438.934,379,441.898,397.7407,452.5497,392.2142,438.934,379" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Widget to StatelessWidget--><g id="link_Widget_StatelessWidget"><path codeline="17" d="M659.8864,68.7853 C674.7124,86.4433 683.526,96.941 698.419,114.678 " fill="none" id="Widget-backto-StatelessWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="648.312,55,655.2913,72.6434,664.4815,64.9271,648.312,55" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Widget to StatefulWidget--><g id="link_Widget_StatefulWidget"><path codeline="18" d="M598.4076,68.8496 C583.7486,86.5076 575.087,96.941 560.361,114.678 " fill="none" id="Widget-backto-StatefulWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="609.905,55,593.7911,65.0171,603.0241,72.682,609.905,55" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Widget to ProxyWidget--><g id="link_Widget_ProxyWidget"><path codeline="19" d="M686.8155,55.7537 C730.2065,73.5817 782.198,94.942 830.608,114.831 " fill="none" id="Widget-backto-ProxyWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="670.166,48.913,684.5352,61.3036,689.0957,50.2039,670.166,48.913" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link ProxyWidget to InheritedWidget--><g id="link_ProxyWidget_InheritedWidget"><path codeline="20" d="M887,181 C887,198.658 887,204.941 887,222.678 " fill="none" id="ProxyWidget-backto-InheritedWidget" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="887,163,881,181,893,181,887,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link StatelessWidget to Container--><g id="link_StatelessWidget_Container"><path codeline="22" d="M718,181 C718,198.658 718,204.941 718,222.678 " fill="none" id="StatelessWidget-backto-Container" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="none" points="718,163,712,181,724,181,718,163" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[XP713i8W38RlFCLUO6_WROc91wFP3fxPg1kcGW8bcuaFRnOq8Z2y0EtNzcz-U6_9y86g0RcrrKMA4OWn_fjkGGamf_u60xrB_5NjddMTmz60JgeHePaaYl_5HuSajshJbD-XhB3LLPGgGT- -HrZOUlYmqUZkAaYqUawyx8WJN1rk6BLI16lp-A0cC990vF7PwEMH-Q1uQiA- -uGe71UyFOnNOP78nn95N2emBm00]--></g></svg>

<p>两外还有如下经常使用的Wiget：</p>
<ul>
<li>PreferredSizeWidget继承自Widget，相关子类有AppBar和TabBar；</li>
<li>LayoutBuilder可以根据parent的布局约束来创建合理的布局；</li>
</ul>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/507c84ae.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/66ec960c.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/66ec960c.html" class="post-title-link" itemprop="url">C++语法手册</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2024-01-13 10:47:20 / 修改时间：15:11:21" itemprop="dateCreated datePublished" datetime="2024-01-13T10:47:20+08:00">2024-01-13</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/C-C/" itemprop="url" rel="index"><span itemprop="name">C/C++</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h2 id="using用法"><a href="#using用法" class="headerlink" title="using用法"></a>using用法</h2><ol>
<li><p>导入命名空间</p>
 <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 导入整个命名空间到当前作用域，这样std::cout就可以写成cout了。</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="comment">// 只导入某个变量到当前作用域 </span></span><br><span class="line"><span class="keyword">using</span> std::cout; </span><br></pre></td></tr></table></figure>

<p> 一般头文件中要避免使用using导入命名空间。否则引入这个头文件的也相当于导入了命名空间，容易带来命名冲突。</p>
</li>
<li><p>指定别名，C++11中可以使用using来指定别名，作用与typedef相同</p>
 <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> T; <span class="comment">// 用 T 代替 int</span></span><br><span class="line"><span class="keyword">using</span> T = <span class="type">int</span>; <span class="comment">// 用 T 代替 int</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>派生类引入基类成员</p>
 <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Base</span> &#123;</span><br><span class="line"><span class="keyword">protected</span>:  <span class="comment">//此处可以改成public，但不能改成private</span></span><br><span class="line">    <span class="type">int</span> value;</span><br><span class="line">    <span class="type">int</span> name;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Derived</span> : <span class="keyword">private</span> Base &#123; <span class="comment">//Base是私有继承</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="comment">//通过Derived的实例可以访问父类的value，但是无法访问父类的name变量</span></span><br><span class="line">    <span class="keyword">using</span> Base::value;  </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

</li>
</ol>
<h2 id="类型转换"><a href="#类型转换" class="headerlink" title="类型转换"></a>类型转换</h2><h3 id="static-cast"><a href="#static-cast" class="headerlink" title="static_cast"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.cppreference.com/w/cpp/language/static_cast">static_cast</a></h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> &#123;&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">D</span> : <span class="keyword">public</span> B &#123;&#125;;</span><br><span class="line"></span><br><span class="line">D d;</span><br><span class="line">B&amp; b = d;</span><br><span class="line">D&amp; newD = <span class="built_in">static_cast</span>&lt;D&amp;&gt;(b);</span><br></pre></td></tr></table></figure>

<p>代码中D和B的继承关系不是虚继承（没有virtual修饰继承关系），如果是虚继承，就无法使用static_cast了。</p>
<h3 id="dynamic-cast"><a href="#dynamic-cast" class="headerlink" title="dynamic_cast"></a><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.cppreference.com/w/cpp/language/dynamic_cast">dynamic_cast</a></h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">test</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">D</span> : <span class="keyword">virtual</span> <span class="keyword">public</span> B &#123;&#125;;</span><br><span class="line"></span><br><span class="line">D d;</span><br><span class="line">B&amp; b = d;</span><br><span class="line">D&amp; newD = <span class="built_in">dynamic_cast</span>&lt;D&amp;&gt;(b); <span class="comment">// downcast</span></span><br><span class="line"></span><br><span class="line">B&amp; newB = <span class="built_in">dynamic_cast</span>&lt;B&amp;&gt;(d); <span class="comment">//可以成功，但无必要，可以直接使用B&amp; newB = d;效率更高</span></span><br></pre></td></tr></table></figure>

<p>上述代码有两个关键点：1）D与B的继承关系通过virtual修饰；2）B包含虚函数。只有这两个条件同时满足才能使用dynamic_cast。另外与static_cast区别是：static_cast必然成功，而dynamic_cast失败的情况会返回target-type类型的空指针。</p>
<h2 id="值分类"><a href="#值分类" class="headerlink" title="值分类"></a>值分类</h2>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/66ec960c.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/99c27b28.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/99c27b28.html" class="post-title-link" itemprop="url">C++智能指针</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2024-01-13 07:34:10 / 修改时间：16:38:20" itemprop="dateCreated datePublished" datetime="2024-01-13T07:34:10+08:00">2024-01-13</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/C-C/" itemprop="url" rel="index"><span itemprop="name">C/C++</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h2 id="std-shared-ptr"><a href="#std-shared-ptr" class="headerlink" title="std::shared_ptr"></a>std::shared_ptr</h2><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://en.cppreference.com/w/cpp/memory/shared_ptr">std::shared_ptr</a>共享智能指针，可以支持多个智能指针共享一个对象实例。shared_ptr持有的实例会在下面场景下被销毁：</p>
<ul>
<li>持有实例的最后一个shared_ptr被销毁；</li>
<li>持有实例的最后一个shared_ptr被另一个智能指针赋值，或者shared_ptr调用了reset();</li>
</ul>
<p><img src="/images/C++/shared_ptr.drawio.svg" alt="shared_ptr"></p>
<p>使用方法：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">shared_ptr&lt;User&gt; sp1 = <span class="built_in">make_shared</span>&lt;User&gt;(<span class="number">1</span>, <span class="string">&quot;sp1&quot;</span>, <span class="string">&quot;123456&quot;</span>);</span><br><span class="line"><span class="function">shared_ptr&lt;User&gt; <span class="title">sp2</span><span class="params">(<span class="keyword">new</span> User(<span class="number">2</span>, <span class="string">&quot;sp2&quot;</span>, <span class="string">&quot;123456&quot;</span>))</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//指针和赋值动作可以分开</span></span><br><span class="line"><span class="function">shared_ptr&lt;User&gt; <span class="title">sp3</span><span class="params">(<span class="literal">nullptr</span>)</span></span>;</span><br><span class="line">sp3 = <span class="built_in">make_shared</span>&lt;User&gt;(<span class="number">3</span>, <span class="string">&quot;sp3&quot;</span>, <span class="string">&quot;123456&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Control Block的ref将会加一</span></span><br><span class="line">audo p4 = sp1;</span><br><span class="line"></span><br><span class="line"><span class="comment">//Control Block和Object都会被交换</span></span><br><span class="line">sp1.<span class="built_in">swap</span>(sp2);</span><br></pre></td></tr></table></figure>

<p>参考：<a target="_blank" rel="noopener external nofollow noreferrer" href="https://learn.microsoft.com/zh-cn/cpp/cpp/how-to-create-and-use-shared-ptr-instances?view=msvc-170">创建和使用 shared_ptr 实例</a></p>
<p>注意：不要使用裸指针来初始化智能指针，会导致多次释放内存造成崩溃：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">test</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    User* user = <span class="keyword">new</span> <span class="built_in">User</span>(<span class="number">0</span>, <span class="string">&quot;Jone&quot;</span>, <span class="string">&quot;12345&quot;</span>);</span><br><span class="line">    <span class="function">shared_ptr&lt;User&gt; <span class="title">p1</span><span class="params">(user)</span></span>;</span><br><span class="line">    <span class="function">shared_ptr&lt;User&gt; <span class="title">p2</span><span class="params">(user)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>当test()函数退出时，p2会先调用User析构，然后p1会再次调用User析构函数，同时两次释放同一块内存，就会导致程序出错。下面是正确的写法：</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/99c27b28.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/77080af6.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/77080af6.html" class="post-title-link" itemprop="url">C++类内存布局</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2024-01-12 22:12:12" itemprop="dateCreated datePublished" datetime="2024-01-12T22:12:12+08:00">2024-01-12</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2024-01-13 16:24:25" itemprop="dateModified" datetime="2024-01-13T16:24:25+08:00">2024-01-13</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/C-C/" itemprop="url" rel="index"><span itemprop="name">C/C++</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Base</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="type">int</span> baseValue;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">baseFun</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">B</span> &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="type">int</span> bValue;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">fb1</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">fb2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">test</span><span class="params">()</span> </span>&#123; cout &lt;&lt; <span class="string">&quot;B::test()&quot;</span> &lt;&lt; endl; &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">C</span> : <span class="keyword">public</span> Base &#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="type">int</span> cValue;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">fc1</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">fc2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">test</span><span class="params">()</span> </span>&#123; cout &lt;&lt; <span class="string">&quot;C::test()&quot;</span> &lt;&lt; endl; &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> : <span class="keyword">public</span> B, <span class="keyword">public</span> C</span><br><span class="line">&#123;</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="type">int</span> aPublicValue;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">fb2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="comment">//virtual void test() &#123; cout &lt;&lt; &quot;A::test()&quot; &lt;&lt; endl; &#125;</span></span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">fc2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">funcA1</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="keyword">virtual</span> <span class="type">void</span> <span class="title">funcA2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line">    <span class="function"><span class="type">void</span> <span class="title">funcA3</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="type">short</span> aPrivateValue;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p><img src="/images/C++%E5%AF%B9%E8%B1%A1%E5%86%85%E5%AD%98%E5%B8%83%E5%B1%80.drawio.svg" alt="C++对象内存布局"></p>
<p>通过VisualStudio来查看A类的内存布局：</p>
<figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">class A	size(28):</span><br><span class="line">	+---</span><br><span class="line"> 0	| +--- (base class B)</span><br><span class="line"> 0	| | &#123;vfptr&#125;</span><br><span class="line"> 4	| | bValue</span><br><span class="line">	| +---</span><br><span class="line"> 8	| +--- (base class C)</span><br><span class="line"> 8	| | +--- (base class Base)</span><br><span class="line"> 8	| | | &#123;vfptr&#125;</span><br><span class="line">12	| | | baseValue</span><br><span class="line">	| | +---</span><br><span class="line">16	| | cValue</span><br><span class="line">	| +---</span><br><span class="line">20	| aPublicValue</span><br><span class="line">24	| aPrivateValue</span><br><span class="line">  	| &lt;alignment member&gt; (size=2)</span><br><span class="line">	+---</span><br><span class="line"></span><br><span class="line">A::$vftable@B@:</span><br><span class="line">	| &amp;A_meta</span><br><span class="line">	|  0</span><br><span class="line"> 0	| &amp;B::fb1 </span><br><span class="line"> 1	| &amp;A::fb2 </span><br><span class="line"> 2	| &amp;B::test </span><br><span class="line"> 3	| &amp;A::funcA1 </span><br><span class="line"> 4	| &amp;A::funcA2 </span><br><span class="line"></span><br><span class="line">A::$vftable@C@:</span><br><span class="line">	| -8</span><br><span class="line"> 0	| &amp;Base::baseFun </span><br><span class="line"> 1	| &amp;C::fc1 </span><br><span class="line"> 2	| &amp;A::fc2 </span><br><span class="line"> 3	| &amp;C::test </span><br><span class="line"></span><br><span class="line">A::fb2 this adjustor: 0</span><br><span class="line">A::fc2 this adjustor: 8</span><br><span class="line">A::funcA1 this adjustor: 0</span><br><span class="line">A::funcA2 this adjustor: 0</span><br></pre></td></tr></table></figure>

<p>从<code>A::$vftable@B@</code>可以看出虚函数表中A和B合并在一起了，并且<code>A::fb2</code>覆盖了<code>B::fb2</code>。而C类的vftable则是独立存储。</p>
<p>B和C两个类都定义了test()函数，而A类则没有覆盖test方法，如果A类调用test方法到底采用的是那个呢？在<code>A::$vftable@B@</code>指向的是<code>B::test</code>。而<code>A::$vftable@C@</code>指向的是<code>C::test</code>。我们通过下面代码进行测试：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    A a;</span><br><span class="line">    <span class="comment">//a.test(); //此处会导致编译错误，因为无法确定test的实现</span></span><br><span class="line">    a.B::<span class="built_in">test</span>(); <span class="comment">//通过限定引用可以解决多义性问题</span></span><br><span class="line">    B&amp; b = <span class="built_in">static_cast</span>&lt;B&amp;&gt;(a);</span><br><span class="line">    b.<span class="built_in">test</span>();  <span class="comment">//打印 B::test()</span></span><br><span class="line">    C* c = <span class="built_in">static_cast</span>&lt;C*&gt;(&amp;a);</span><br><span class="line">    c-&gt;<span class="built_in">test</span>(); <span class="comment">//打印 C::test()</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>所以基于A类的实例是无法调用test函数的，但是把A类转换成B/C的引用或者指针后，就能调用test方法了，但只能分别调用自己的函数实现。</p>
<p>我们现在把C继承Base使用virtual进行修饰，代码改动如下：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">C</span> : <span class="keyword">public</span> <span class="keyword">virtual</span> Base</span><br></pre></td></tr></table></figure>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/77080af6.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/9b085480.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/9b085480.html" class="post-title-link" itemprop="url">Android性能优化</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2024-01-05 07:07:55" itemprop="dateCreated datePublished" datetime="2024-01-05T07:07:55+08:00">2024-01-05</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2024-01-09 11:52:15" itemprop="dateModified" datetime="2024-01-09T11:52:15+08:00">2024-01-09</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h2 id="启动优化"><a href="#启动优化" class="headerlink" title="启动优化"></a>启动优化</h2><p>延迟加载，比如通过IdleHandler在系统空闲时加载模块<br>异步初始化</p>
<p>缺点：界面展示了，但是用户操控出现卡断</p>
<p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.csdn.net/github_35186068/article/details/86486033">Android 性能优化 - 启动优化</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://dzone.com/articles/how-to-capture-heap-dump-from-android-app">How to Capture Heap Dump From an Android App</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.com/topic/performance/tracing/navigate-report">浏览 Systrace 报告</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://source.android.google.cn/devices/tech/dalvik/dex-format?hl=zh-cn">Dalvik 可执行文件格式</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.imooc.com/article/317405">应用性能优化之VerifyClass</a></p>
<h2 id="渲染性能优化"><a href="#渲染性能优化" class="headerlink" title="渲染性能优化"></a>渲染性能优化</h2><p>防止因视图层次结构导致性能下降包括两个目标：一个是实现视图层次结构扁平化，一个是减少 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/topic/performance/rendering/optimizing-view-hierarchies?hl=zh-cn#double">Double Taxation</a>。布局耗时过长的一个常见原因是，View 对象的层次结构互相嵌套(层级过深)。每个嵌套的布局对象都会增加布局阶段的开销。层次结构越扁平，完成布局阶段所需的时间越少。</p>
<p><strong>优化方案：</strong></p>
<ul>
<li>使用 ConstraintLayout 而非 RelativeLayout 或 LinearLayout，因为这么做通常更高效，并且减少了布局的嵌套。不过，对于可通过 FrameLayout 实现的简单布局，还是建议使用 FrameLayout；</li>
<li>如果使用 RelativeLayout 类，则可通过使用未设权重的嵌套 LinearLayout 视图，以更低的开销达到同样的效果。但是，如果您使用的是嵌套的加权 LinearLayout 视图，则布局开销会高得多，因为它需要多次布局传递；</li>
<li>使用 RecyclerView 而不要使用 ListView，因为前者可以回收各个列表项的布局，这种方式不仅效率更高，而且可以提升滚动性能。</li>
<li>布局中使用 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/develop/ui/views/layout/improving-layouts/reusing-layouts?hl=zh-cn#Merge">&lt;merge&gt;</a>来减少布局层次。</li>
<li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/develop/ui/views/layout/improving-layouts/loading-ondemand?hl=zh-cn">使用ViewStub延迟加载视图</a></li>
<li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/topic/performance/rendering/overdraw?hl=zh-cn#rt">降低透明度</a>，比如一个字体颜色不要使用透明度的值，要使用RGB，而不是ARGB。</li>
<li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/topic/performance/rendering/overdraw?hl=zh-cn#rubil">移除布局中不必要的背景</a></li>
</ul>
<p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/topic/performance/rendering/optimizing-view-hierarchies?hl=zh-cn">性能和视图层次结构</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/jetpack/compose/performance?hl=zh-cn">Jetpack Compose 性能</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/topic/performance/rendering/inspect-gpu-rendering?hl=zh-cn#debug_overdraw">检查 GPU 渲染速度和过度绘制</a><br><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/quality/technical?hl=zh-cn">Android技术质量</a> 是谷歌官方介绍的性能检查和优化措施。</p>
<p>频繁GC：申请大量对象、图片内存占用</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/9b085480.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/826e5a44.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/826e5a44.html" class="post-title-link" itemprop="url">JetpackCompose key的使用</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2024-01-04 11:41:19 / 修改时间：11:51:56" itemprop="dateCreated datePublished" datetime="2024-01-04T11:41:19+08:00">2024-01-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/JetpackCompose/" itemprop="url" rel="index"><span itemprop="name">JetpackCompose</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Preview</span></span><br><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">MyDemo</span><span class="params">()</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> contents <span class="keyword">by</span> remember &#123;</span><br><span class="line">        mutableStateOf(listOf(<span class="string">&quot;str1&quot;</span>, <span class="string">&quot;str0&quot;</span>))</span><br><span class="line">    &#125;</span><br><span class="line">    Column(</span><br><span class="line">        modifier = Modifier.fillMaxSize(),</span><br><span class="line">        horizontalAlignment = Alignment.CenterHorizontally</span><br><span class="line">    ) &#123;</span><br><span class="line">        ElevatedButton(onClick = &#123;</span><br><span class="line">            <span class="keyword">val</span> list = mutableListOf&lt;String&gt;()</span><br><span class="line">            list.add(<span class="string">&quot;str<span class="subst">$&#123;contents.size&#125;</span>&quot;</span>)</span><br><span class="line">            list.addAll(contents)</span><br><span class="line">            contents = list</span><br><span class="line">        &#125;) &#123;</span><br><span class="line">            Text(text = <span class="string">&quot;顶部插入&quot;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (txt <span class="keyword">in</span> contents) &#123;</span><br><span class="line">            key(txt) &#123;</span><br><span class="line">                DemoText(text = txt)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        DemoText(text = <span class="string">&quot;Hello1&quot;</span>)</span><br><span class="line">        DemoText(text = <span class="string">&quot;Hello2&quot;</span>)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">DemoText</span><span class="params">(text: <span class="type">String</span>)</span></span> &#123;</span><br><span class="line">    Log.d(<span class="string">&quot;SecondActivity&quot;</span>, <span class="string">&quot;[rjy] DemoText=<span class="variable">$text</span>&quot;</span>)</span><br><span class="line">    Text(text = text)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>上述代码中，如果不使用<code>key</code>，就会导致每次顶部插入时，for循环内部的组合项都会被重新构造。加上<code>key</code>后，就会只构造text变化的DemoText。另外对于for循环外部的两个DemoText时不会重新构造的，因为这两个组合项的输入参数时不变的。</p>
<p>参考：<a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/jetpack/compose/lifecycle?hl=zh-cn">可组合项的生命周期</a></p>

          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/826e5a44.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/765590d3.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/765590d3.html" class="post-title-link" itemprop="url">Shadow插件化框架原理</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-12-30 22:18:12" itemprop="dateCreated datePublished" datetime="2023-12-30T22:18:12+08:00">2023-12-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2024-01-03 16:12:23" itemprop="dateModified" datetime="2024-01-03T16:12:23+08:00">2024-01-03</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h2 id="sample项目调试"><a href="#sample项目调试" class="headerlink" title="sample项目调试"></a>sample项目调试</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">sample-host-debug.apk -&gt; projects/sample/source/sample-host</span><br><span class="line">├── sample-constant -&gt; projects/sample/source/sample-constant</span><br><span class="line">└── sample-host-lib -&gt; projects/sample/source/sample-host-lib</span><br><span class="line"></span><br><span class="line">pluginmanager.apk -&gt; projects/sample/source/sample-manager</span><br><span class="line">└── sample-constant -&gt; projects/sample/source/sample-constant</span><br><span class="line"></span><br><span class="line">sample-runtime-debug.apk -&gt; projects/sample/source/sample-plugin/sample-runtime</span><br><span class="line">└── activity-container -&gt; projects/sdk/core/activity-container (maven)</span><br><span class="line"></span><br><span class="line">sample-loader-debug.apk -&gt; projects/sample/source/sample-plugin/sample-loader</span><br><span class="line">├── sample-host-lib -&gt; projects/sample/source/sample-host-lib (compileOnly)</span><br><span class="line">└── sample-constant -&gt; projects/sample/source/sample-constant</span><br></pre></td></tr></table></figure>

<p>下载Shadow工程后，在根目录执行<code>./gradlew build</code>等待编译成功，然后通过adb安装：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adb install projects/sample/source/sample-host/build/outputs/apk/debug/sample-host-debug.apk</span><br></pre></td></tr></table></figure>

<p>在sample-host-debug.apk的assets目录下包含<code>pluginmanager.apk</code>和<code>plugin-debug.zip</code>，其中plugin-debug.zip包含的文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── config.json</span><br><span class="line">├── sample-app-plugin-debug.apk</span><br><span class="line">├── sample-app-plugin-debug2.apk</span><br><span class="line">├── sample-base-plugin-debug.apk</span><br><span class="line">├── sample-loader-debug.apk</span><br><span class="line">└── sample-runtime-debug.apk</span><br></pre></td></tr></table></figure>

<p>config.json文件内容如下：</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line"> <span class="attr">&quot;compact_version&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">  <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">  <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line">  <span class="number">3</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;pluginLoader&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;apkName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-loader-debug.apk&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hash&quot;</span><span class="punctuation">:</span> <span class="string">&quot;476180733ADFE69DDBE88CADAD473A4B&quot;</span></span><br><span class="line"> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;plugins&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">  <span class="punctuation">&#123;</span></span><br><span class="line">   <span class="attr">&quot;partKey&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-plugin-app&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;apkName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-app-plugin-debug.apk&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;dependsOn&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;sample-base&quot;</span></span><br><span class="line">   <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;businessName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-plugin-app&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;hostWhiteList&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;com.tencent.shadow.sample.host.lib&quot;</span></span><br><span class="line">   <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;hash&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ECF851E261BF1B8D165D9AEB7C4C3699&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="punctuation">&#123;</span></span><br><span class="line">   <span class="attr">&quot;partKey&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-plugin-app2&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;apkName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-app-plugin-debug2.apk&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;dependsOn&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;sample-base&quot;</span></span><br><span class="line">   <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;businessName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-plugin-app2&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;hostWhiteList&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;com.tencent.shadow.sample.host.lib&quot;</span></span><br><span class="line">   <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;hash&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ECF851E261BF1B8D165D9AEB7C4C3699&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="punctuation">&#123;</span></span><br><span class="line">   <span class="attr">&quot;partKey&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-base&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;apkName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-base-plugin-debug.apk&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;businessName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-plugin-app&quot;</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;hostWhiteList&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;com.tencent.shadow.sample.host.lib&quot;</span></span><br><span class="line">   <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">   <span class="attr">&quot;hash&quot;</span><span class="punctuation">:</span> <span class="string">&quot;18CA96C8EA499DC657ED6DE44B050728&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"> <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;runtime&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;apkName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;sample-runtime-debug.apk&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hash&quot;</span><span class="punctuation">:</span> <span class="string">&quot;364BAB0EB1B8CD345D15D767D1FA8DC7&quot;</span></span><br><span class="line"> <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;UUID&quot;</span><span class="punctuation">:</span> <span class="string">&quot;F5574A0D-D937-42C0-93A6-35E190CCA955&quot;</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="number">4</span><span class="punctuation">,</span></span><br><span class="line"> <span class="attr">&quot;UUID_NickName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.1.5&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="插件启动过程"><a href="#插件启动过程" class="headerlink" title="插件启动过程"></a>插件启动过程</h2><p>在sample代码中启动插件Activity会通过一个跳板<code>PluginLoadActivity</code>，跳板Activity会展示插件loading view，从而避免插件启动过程中的黑屏给用户带来困惑。</p>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/765590d3.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/7ed69fd0.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | 任建勇的博客">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/posts/7ed69fd0.html" class="post-title-link" itemprop="url">Android屏幕分辨率适配</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-11-03 11:20:03" itemprop="dateCreated datePublished" datetime="2023-11-03T11:20:03+08:00">2023-11-03</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-11-18 09:57:09" itemprop="dateModified" datetime="2023-11-18T09:57:09+08:00">2023-11-18</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>Android屏幕分辨率适配一般有三种方案：</p>
<ol>
<li>通过百分比的形式进行布局<ul>
<li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/training/constraint-layout">ConstraintLayout</a>使用bias可以配置百分比，参考<a target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.csdn.net/shulianghan/article/details/97102389">ConstraintLayout 偏移 ( Bias ) 计算方式详解</a>、<a target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.51cto.com/u_16099341/6585721">android中的各种constrainlayout android constraintlayout百分比</a></li>
<li>使用<a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/reference/kotlin/androidx/percentlayout/widget/PercentRelativeLayout">PercentRelativeLayout</a>等，这个是support库中，现在已经标记为deprecated，推荐使用ConstraintLayout</li>
</ul>
</li>
<li>动态适配屏幕分辨率，通过一系列算法去计算每个view在用户手机屏幕中应该的宽高，从而达到一个适配效果;</li>
<li>静态适配屏幕分辨率，就是通过工具生成各种屏幕尺寸的xml文件。</li>
</ol>
<h2 id="ConstraintLayout进行百分比布局"><a href="#ConstraintLayout进行百分比布局" class="headerlink" title="ConstraintLayout进行百分比布局"></a>ConstraintLayout进行百分比布局</h2><p><code>ConstraintLayout</code>中，当子View尺寸设置为MATCH_CONSTRAINT（0dp）时，默认行为是占据所有可用空间，但是可以通过<code>layout_constraintHeight_percent</code>和<code>layout_constraintWidth_percent</code>来设置为占用父View的百分比，注意，这个百分比是整个父View的宽高的百分比，而不是可用空间的百分比。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">androidx.constraintlayout.widget.ConstraintLayout</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_width</span>=<span class="string">&quot;match_parent&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_height</span>=<span class="string">&quot;match_parent&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">View</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">&quot;0dp&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">&quot;0dp&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:background</span>=<span class="string">&quot;#00eeee&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintTop_toTopOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintBottom_toBottomOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintStart_toStartOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintEnd_toEndOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintHeight_percent</span>=<span class="string">&quot;.5&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintWidth_percent</span>=<span class="string">&quot;.5&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">androidx.constraintlayout.widget.ConstraintLayout</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>通过bias来设置位置偏移，下面用法可以让子View左边与parent的间距占比为20%，而不是默认的50%。详细介绍可参考<a target="_blank" rel="noopener external nofollow noreferrer" href="https://developer.android.google.cn/reference/androidx/constraintlayout/widget/ConstraintLayout#centering-positioning-and-bias">Centering positioning and bias</a>。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">androidx.constraintlayout.widget.ConstraintLayout</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_width</span>=<span class="string">&quot;match_parent&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_height</span>=<span class="string">&quot;match_parent&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">View</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:id</span>=<span class="string">&quot;@+id/test_view&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">&quot;100dp&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">&quot;100dp&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:background</span>=<span class="string">&quot;#00eeee&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintTop_toTopOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintBottom_toBottomOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintStart_toStartOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintEnd_toEndOf</span>=<span class="string">&quot;parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintHorizontal_bias</span>=<span class="string">&quot;0.2&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">app:layout_constraintVertical_bias</span>=<span class="string">&quot;0.2&quot;</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">androidx.constraintlayout.widget.ConstraintLayout</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h2 id="静态屏幕适配"><a href="#静态屏幕适配" class="headerlink" title="静态屏幕适配"></a>静态屏幕适配</h2><p>通过AndroidStudio的<a target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.csdn.net/fesdgasdgasdg/article/details/52325590">ScreenMatch</a>插件生成不同分辨率的dimens资源文件来进行适配。该插件会基于<code>res/values/dimens.xml</code>生成不同分辨率的比如：</p>
<figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">res/values-sw240dp/dimens.xml</span><br><span class="line">res/values-sw320dp/dimens.xml</span><br><span class="line">res/values-sw384dp/dimens.xml</span><br><span class="line">res/values-sw392dp/dimens.xml</span><br><span class="line">res/values-sw400dp/dimens.xml</span><br><span class="line">res/values-sw410dp/dimens.xml</span><br><span class="line">res/values-sw411dp/dimens.xml</span><br><span class="line">res/values-sw432dp/dimens.xml</span><br></pre></td></tr></table></figure>
          <!--noindex-->
            <div class="post-button">
              <a class="btn" href="/posts/7ed69fd0.html#more" rel="contents">
                阅读全文 &raquo;
              </a>
            </div>
          <!--/noindex-->
        
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><span class="space">&hellip;</span><a class="page-number" href="/page/7/">7</a><a class="extend next" rel="next" title="下一页" aria-label="下一页" href="/page/2/"><i class="fa fa-angle-right"></i></a>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 
    <span itemprop="copyrightYear">2024</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">Jason</span>
  </div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener external nofollow noreferrer" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener external nofollow noreferrer" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.umd.js" integrity="sha256-oyhjPiYRWGXaAt+ny/mTMWOnN1GBoZDUQnzzgC7FRI4=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>


  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.5.0/mermaid.min.js","integrity":"sha256-K7oJiQlDulzl24ZUFOywuYme1JqBBvQzK6m8qHjt9Gk="}}</script>
  <script type="module" src="/js/zenuml-definition-074a43fa.js"></script>
  <script type="module" src="/js/mermaid-zenuml.esm.min.mjs"></script>
  <script src="/js/third-party/tags/mermaid.js"></script>


  <script src="/js/third-party/fancybox.js"></script>



  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
